package com.interview.rpc.server;

import com.interview.rpc.protocol.Request;
import com.interview.rpc.protocol.Response;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

import java.lang.reflect.Method;
import java.util.Map;

/**
 * RPC服务器处理器
 * 
 * 处理客户端发送的RPC请求，调用本地服务并将结果返回给客户端
 */
public class RpcServerHandler extends ChannelInboundHandlerAdapter {
    
    // 存储服务接口名与实现类实例的映射关系
    private Map<String, Object> serviceMap;
    
    public RpcServerHandler(Map<String, Object> serviceMap) {
        this.serviceMap = serviceMap;
    }
    
    /**
     * 处理接收到的数据
     * 
     * @param ctx ChannelHandlerContext对象，用于与客户端通信
     * @param msg 接收到的数据，在这里应该是Request对象
     * @throws Exception
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        // 将接收到的数据转换为Request对象
        Request request = (Request) msg;
        
        // 创建响应对象
        Response response = new Response();
        // 设置请求ID，用于匹配请求和响应
        response.setRequestId(request.getRequestId());
        
        try {
            // 根据接口名称从服务映射中获取服务实现类实例
            Object serviceBean = serviceMap.get(request.getClassName());
            if (serviceBean == null) {
                // 如果找不到对应的服务实现，返回404错误
                response.setCode(404);
                response.setMessage("服务未找到: " + request.getClassName());
                response.setData(null);
            } else {
                // 获取服务实现类的Class对象
                Class<?> serviceClass = serviceBean.getClass();
                // 根据方法名和参数类型获取要调用的方法
                Method method = serviceClass.getMethod(request.getMethodName(), request.getParameterTypes());
                // Fastjson 反序列化后数值类型可能退化为 Integer 等，执行反射前先对参数做一次按签名类型的转换
                Object[] resolvedParameters = convertParameters(request.getParameterTypes(), request.getParameters());
                // 通过反射调用方法并获取结果
                Object result = method.invoke(serviceBean, resolvedParameters);
                
                // 设置成功响应
                response.setCode(200);
                response.setMessage("success");
                response.setData(result);
            }
        } catch (Exception e) {
            // 如果调用过程中出现异常，返回500错误
            response.setCode(500);
            response.setMessage("服务器内部错误: " + e.getMessage());
            response.setData(null);
        }
        
        // 将响应发送给客户端
        ctx.writeAndFlush(response);
    }
    
    private Object[] convertParameters(Class<?>[] parameterTypes, Object[] parameters) {
        if (parameterTypes == null || parameters == null || parameterTypes.length != parameters.length) {
            return parameters;
        }
        // 逐个参数按声明的目标类型做匹配转换，保证反射调用不会因为类型不吻合而失败
        Object[] converted = new Object[parameters.length];
        for (int i = 0; i < parameters.length; i++) {
            converted[i] = convertValue(parameters[i], parameterTypes[i]);
        }
        return converted;
    }
    
    private Object convertValue(Object value, Class<?> targetType) {
        if (value == null || targetType == null) {
            return value;
        }
        if (targetType.isPrimitive()) {
            targetType = primitiveToWrapper(targetType);
        }
        if (targetType.isInstance(value)) {
            return value;
        }
        if (Number.class.isAssignableFrom(targetType) && value instanceof Number) {
            Number number = (Number) value;
            if (targetType == Long.class) {
                return number.longValue();
            } else if (targetType == Integer.class) {
                return number.intValue();
            } else if (targetType == Short.class) {
                return number.shortValue();
            } else if (targetType == Byte.class) {
                return number.byteValue();
            } else if (targetType == Double.class) {
                return number.doubleValue();
            } else if (targetType == Float.class) {
                return number.floatValue();
            }
        }
        if (targetType == Boolean.class && value instanceof Boolean) {
            return value;
        }
        if (targetType == String.class) {
            return String.valueOf(value);
        }
        return value;
    }
    
    private Class<?> primitiveToWrapper(Class<?> primitiveType) {
        if (primitiveType == int.class) {
            return Integer.class;
        } else if (primitiveType == long.class) {
            return Long.class;
        } else if (primitiveType == short.class) {
            return Short.class;
        } else if (primitiveType == byte.class) {
            return Byte.class;
        } else if (primitiveType == double.class) {
            return Double.class;
        } else if (primitiveType == float.class) {
            return Float.class;
        } else if (primitiveType == boolean.class) {
            return Boolean.class;
        } else if (primitiveType == char.class) {
            return Character.class;
        }
        return primitiveType;
    }
    
    /**
     * 处理异常
     * 
     * @param ctx ChannelHandlerContext对象
     * @param cause 异常对象
     * @throws Exception
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        // 打印异常堆栈信息
        cause.printStackTrace();
        // 关闭与客户端的连接
        ctx.close();
    }
}
